using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using AutoMapper;
using SapaFinance.DTO;
using SapaFinance.Domain.Model;
using SapaFinance.GenericRepository;
using Telerik.Web.Mvc.UI;

namespace SapaFinance.Services
{
    public interface ICfoService
    {
        IEnumerable<SelectListItem> GetSelectedListById(Guid id);
        IEnumerable<CFO> GetCfoList(IEnumerable<TreeViewItem> checkedCfo);
        IEnumerable<CFO> GetAllCfo();
        CFO GetCfo(Guid selectedCfo);
        IEnumerable<CFOTree> GetCfoTreeByCorporationId(Guid id);
        ICorporationService CorporationService { get; set; }
        IEnumerable<CfoDTO> GetListDTO();
        void Insert(CfoDTO dto);
        void Delete(Guid id);
        void Update(CfoDTO dto);
    }

    public class CfoService : ICfoService
    {
        private readonly IGenericRepository<CFO, Guid> _cfoRepository;
        private readonly IMappingEngine _mappingEngine;
        private readonly IEntityFactory _entityFactory;
        private readonly IUnitOfWork _unitOfWork;

        public CfoService(IGenericRepository<CFO, Guid> cfoRepository, IMappingEngine mappingEngine, IEntityFactory entityFactory, IUnitOfWork unitOfWork)
        {
            _cfoRepository = cfoRepository;
            _mappingEngine = mappingEngine;
            _entityFactory = entityFactory;
            _unitOfWork = unitOfWork;
        }

        public ICorporationService CorporationService { get; set; }

        #region ICfoService Members

        public IEnumerable<SelectListItem> GetSelectedListById(Guid id)
        {
            return Guid.Empty.Equals(id)
                       ? _mappingEngine.Map<IEnumerable<CFO>, IEnumerable<SelectListItem>>(_cfoRepository.GetAll())
                       : _mappingEngine.Map<CFO, IEnumerable<SelectListItem>>(_cfoRepository.GetById(id));
        }

        public IEnumerable<CFO> GetCfoList(IEnumerable<TreeViewItem> checkedCfo)
        {
            var cfos = new List<CFO>();
            if (checkedCfo != null){
                var cfoGuids = checkedCfo.Select(x => Guid.Parse(x.Value));
                cfos.AddRange(cfoGuids.Select(x => _cfoRepository.GetById(x)));
            }
            return cfos;
        }

        public CFO GetCfo(Guid id)
        {
            return _cfoRepository.GetById(id);
        }

        public IEnumerable<CFO> GetAllCfo()
        {
            return _cfoRepository.GetAll();
        }

        public IEnumerable<CFOTree> GetCfoTreeByCorporationId(Guid id)
        {
            var allCfo = _mappingEngine.Map<IEnumerable<CFO>, IEnumerable<TreeViewItem>>(GetAllCfo());
            var corporation = CorporationService.GetCorporation(id);
            if (corporation != null){
                var selectedCfo = _mappingEngine.Map<IEnumerable<CFO>, IEnumerable<TreeViewItem>>(corporation.Cfos);
                selectedCfo.All(x => x.Checked = true);
                return new List<CFOTree>{
                                            new CFOTree{
                                                           Items = allCfo,
                                                           SelectedItems = selectedCfo
                                                       }
                                        };
            }
            return new List<CFOTree>{
                                        new CFOTree{
                                                       Items = allCfo,
                                                       //SelectedItems = selectedCfo
                                                   }
                                    };
        }
        public IEnumerable<CfoDTO> GetListDTO()
        {
            return _mappingEngine.Map<IEnumerable<CFO>, IEnumerable<CfoDTO>>(_cfoRepository.GetAll());
        }
        public virtual void Insert(CfoDTO dto)
        {
            var entity = _entityFactory.BuildCfo(dto);
            _cfoRepository.Insert(entity);
            _unitOfWork.Flush();
        }

        public virtual void Delete(Guid id)
        {
            var entity = _cfoRepository.GetById(id);
            _cfoRepository.Delete(entity);
            _unitOfWork.Flush();
        }

        public virtual void Update(CfoDTO dto)
        {
            var entity = _cfoRepository.GetById(dto.UID);
            entity.Name = dto.Name;
            _cfoRepository.Update(entity);
            _unitOfWork.Flush();
        }

        #endregion
    }
}